package com.zkrt.upms.common.util;

import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;

@Slf4j
public class SocketUtil {


    private static Socket socket; //socket连接
    private static boolean connection = false;//socket是否连接
    private static int connectcount = 0;

    /**
     * 数据发送
     *
     * @param host
     * @param port
     * @param content
     * @return
     * @throws Exception
     */
    public static String sendMessage(String host, Integer port, String content) throws Exception {
        log.info("[Socket推送] -> host:{} , port:{}", host, port);
        String logText = openSendMsg(content, host, port);
        if (ObjectUtil.isEmpty(logText)) {
            return null;
        }
        log.info("[Socket结果] -> {}", logText);
        return logText;
    }


    public static String openSendMsg(String sendData, String ip, Integer port) {
        // 打开连接
        open(ip, port);
        if (connection == false) {
            log.info("[Connection连接失败]");
            return null;
        }
        // 发送报文并获取返回报文
        log.info("[开始推送HJ212数据] -> {}", sendData);
        String resultData = sendAndRecMsg(sendData.getBytes());
        close();
        return resultData;
    }

    public static String sendAndRecMsg(byte[] message) {
        if (message == null) {
            return null;
        }
        try {
            InputStream in = socket.getInputStream();  //获取输入流，并创建相应的数据输入流
            OutputStream out = socket.getOutputStream();//获取输出流，并创建相应的数据输出流

            out.write(message);
            out.flush();

            int count = 0;
            int k = 0;
            while (count == 0 && k < 100) {
                count = in.available();
                k++;
                Thread.sleep(200);
            }
            byte[] receive = new byte[count];
            int readCount = 0; // 已经成功读取的字节的个数
            while (readCount < count) {
                readCount += in.read(receive, readCount, count - readCount);
            }

            if (receive.length == 0) {
                return null;
            }
            String strdata = new String(receive);
            return strdata;

        } catch (Exception e) {
            log.error("[推送异常] -> {}", e.getMessage());
        }
        return null;
    }

    /**
     * 打开socket连接
     */
    public static boolean open(String ip, Integer port) {
        while (connectcount < 30 && !connection) {
            try {
                socket = new Socket(); //重新连接需要new Socket，否则报错
                socket.connect(new InetSocketAddress(ip, port), 0);
                connection = true;
                connectcount = 0;
                log.info("[Socket连接成功]");
            } catch (Exception ex) {
                connectcount++;
                log.error("[服务器建立Socket连接] -> 第 {} 次失败，异常原因：{}", connectcount, ex.getMessage());
                try {
                    if (connectcount <= 15) {
                        Thread.sleep(10000);
                    } else if (connectcount < 10) {
                        Thread.sleep(30000);
                    } else if (connectcount < 15) {
                        Thread.sleep(60000);
                    }
                    socket.close();//建立失败，以防万一，close
                } catch (InterruptedException e) {
                    log.error("[服务器关闭Socket连接异常] -> {}", e.getMessage());
                } catch (IOException e) {
                    log.error("[服务器关闭Socket连接异常] -> {}", e.getMessage());
                }
            }
        }
        return connection;
    }

    /**
     * 关闭socket
     */
    public static void close() {
        if (connection) {
            try {
                socket.close();
                log.info("[Socket关闭成功]");
            } catch (IOException e) {
                log.error("[Socket关闭失败] -> {}", e.getMessage());
            }
            connection = false;
        }
    }


}
